iT邦幫忙

2025 iThome 鐵人賽

DAY 1
1
Modern Web

React TDD 實戰:用 Vitest 打造可靠的前端應用系列 第 1

Day 01 - 環境設置與第一個測試 🚀

  • 分享至 

  • xImage
  •  

今天要做什麼?

歡迎來到「React TDD 實戰:用 Vitest 打造可靠的前端應用」系列!

想像一下,你是一位新手開發者,剛加入一個重視程式品質的團隊。主管交給你第一個任務:「我們要建立一個 React 專案,而且要從第一天就導入測試文化。」聽起來很有挑戰性?別擔心,讓我們從最基礎的開始,一步步建立起 TDD 的基礎。

今天是我們 TDD 旅程的第一天,我們要設置 React + TypeScript + Vitest 的開發環境,並寫下第一個測試。就像學開車一樣,我們先在安全的練習場地熟悉基本操作。

學習目標

今天結束後,你將學會:

  • 建立 React + TypeScript + Vitest 開發環境
  • 了解 Vitest 的基本配置
  • 寫出第一個單元測試
  • 體驗測試失敗到通過的完整過程
  • 理解測試檔案的組織結構

TDD 學習地圖

第一階段:打好基礎(Day 1-10)
├── Day 01 - 環境設置與第一個測試 ★ 今天在這裡
├── ...
└── (更多精彩內容待續)

建立專案 🏗️

首先建立一個全新的 React 專案:

npm create vite@latest react-tdd-demo -- --template react-ts
cd react-tdd-demo
npm install

安裝測試相關套件

npm install -D vitest @vitest/ui jsdom

配置 Vitest

建立 vite.config.ts

import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [react()],
  test: {
    globals: true,
    environment: 'jsdom',
    setupFiles: ['./tests/setup.ts'],
  },
})

建立 tests/setup.ts

// 全域測試設定檔
// 這裡可以放置所有測試共用的設定

更新 package.json

package.json 中新增測試指令:

{
  "scripts": {
    "dev": "vite",
    "build": "tsc && vite build",
    "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
    "preview": "vite preview",
    "test": "vitest",
    "test:ui": "vitest --ui",
    "coverage": "vitest run --coverage"
  }
}

第一個測試:計算機函數 🧮

讓我們從最簡單的例子開始 - 一個計算機模組。

建立 tests/day01/calculator.test.ts

import { describe, it, expect } from 'vitest'

// 先寫測試,這時 calculator 模組還不存在
import { add } from '../../src/calculator'

describe('Calculator', () => {
  it('adds two numbers correctly', () => {
    const result = add(2, 3)
    expect(result).toBe(5)
  })
})

執行測試(紅燈階段)🔴

npm test

你會看到測試失敗的訊息,因為 calculator 模組還不存在。這就是 TDD 的「紅燈」階段 - 先寫測試,看它失敗。

實作程式碼(綠燈階段)🟢

建立 src/calculator.ts

export function add(a: number, b: number): number {
  return a + b
}

再次執行測試:

npm test

現在測試應該通過了!這就是「綠燈」階段。

新增更多測試案例

更新 tests/day01/calculator.test.ts

import { describe, it, expect } from 'vitest'
import { add, subtract, multiply, divide } from '../../src/calculator'

describe('Calculator', () => {
  it('adds two numbers correctly', () => {
    const result = add(2, 3)
    expect(result).toBe(5)
  })

  it('adds negative numbers correctly', () => {
    const result = add(-2, 3)
    expect(result).toBe(1)
  })

  it('subtracts two numbers correctly', () => {
    const result = subtract(5, 3)
    expect(result).toBe(2)
  })

  it('multiplies two numbers correctly', () => {
    const result = multiply(4, 3)
    expect(result).toBe(12)
  })

  it('divides two numbers correctly', () => {
    const result = divide(10, 2)
    expect(result).toBe(5)
  })

  it('handles division by zero', () => {
    const result = divide(10, 0)
    expect(result).toBe(Infinity)
  })
})

完整實作 calculator

更新 src/calculator.ts

export function add(a: number, b: number): number {
  return a + b
}

export function subtract(a: number, b: number): number {
  return a - b
}

export function multiply(a: number, b: number): number {
  return a * b
}

export function divide(a: number, b: number): number {
  return a / b
}

執行測試確認

npm test

所有測試都應該通過!

今天學到什麼?

1. 測試驅動開發的基本循環

  • 紅燈:先寫測試,看它失敗
  • 綠燈:寫最少的程式碼讓測試通過
  • 重構:改善程式碼品質

2. Vitest 基礎概念

  • describe: 測試套件,用來組織相關的測試
  • it: 個別測試案例
  • expect: 斷言函數,驗證結果

3. 測試檔案組織

  • 測試檔案放在 tests/ 目錄
  • 按天數組織學習內容(如 tests/day01/calculator.test.ts
  • 使用 .test.ts 後綴命名
  • 測試檔案結構應該反映被測試的程式碼結構

4. TypeScript 在測試中的價值

  • 編譯時期就能發現錯誤
  • IDE 提供更好的自動完成
  • 程式碼更容易維護

今天的收穫

今天我們完成了 TDD 學習旅程的第一步!透過建立 React + TypeScript + Vitest 環境,我們學會了:

  • 如何設置現代化的測試環境
  • TDD 的基本循環:紅燈 → 綠燈 → 重構
  • 測試案例的基本結構和組織方式
  • TypeScript 在測試中帶來的型別安全優勢

測試執行選項

Vitest 提供多種執行測試的方式:

# 監聽模式(預設)
npm test

# 單次執行
npm run test run

# 使用 UI 介面
npm run test:ui

# 產生覆蓋率報告
npm run coverage

常見問題解決 🔧

1. TypeScript 編譯錯誤

如果遇到「Cannot find module」錯誤,確認 tsconfig.json 的路徑設定:

{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@/*": ["src/*"]
    }
  }
}

2. Vitest 找不到測試檔案

確保測試檔案符合以下命名規則之一:

  • *.test.ts
  • *.spec.ts
  • 位於 tests/ 目錄下

3. jsdom 相關錯誤

如果看到 document is not defined 錯誤,確認 vite.config.ts 有設定:

test: {
  environment: 'jsdom'
}

測試組織最佳實踐

每個測試都應該遵循 AAA 模式:

  1. Arrange(準備):設定測試資料和環境
  2. Act(執行):執行要測試的功能
  3. Assert(驗證):檢查結果是否符合預期

小挑戰 🎯

試著為計算機新增以下功能:

  1. 餘數運算:實作 modulo(a, b) 函數
  2. 次方運算:實作 power(base, exponent) 函數
  3. 錯誤處理:當輸入不是數字時該如何處理?

💡 提示:記得先寫測試再實作功能!

總結

今天我們成功建立了 React + TypeScript + Vitest 的測試環境,並完成了第一個單元測試。雖然例子很簡單,但我們已經體驗了完整的 TDD 流程:

  1. 先寫測試(紅燈)🔴
  2. 實作功能(綠燈)🟢
  3. 確保測試通過 ✅

記住,TDD 不只是一種測試技術,更是一種設計思維。透過先寫測試,我們被迫思考程式的介面和行為,這能幫助我們寫出更好的程式碼。

明天我們將深入了解斷言函數的威力,學習如何寫出更有表達力的測試。準備好了嗎?繼續加油! 💪


下一篇
Day 02 - 認識斷言(Assertions) 🚀
系列文
React TDD 實戰:用 Vitest 打造可靠的前端應用9
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言